/*
 * @Description: 
 * @Author: zheng yiliang
 * @Date: 2021-03-17 20:15:59
 * @LastEditTime: 2021-06-06 11:15:51
 * @LastEditors: zheng yiliang
 */
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const fs = require('fs')
const logger = require('morgan')
const FileStreamRotator = require('file-stream-rotator')
// const session = require('express-session')

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var rolesRouter = require('./routes/roles');
var menusRouter = require('./routes/menus');
var categoryRouter = require('./routes/category');
var tagsRouter = require('./routes/tags');
var articleRouter = require('./routes/article');
var linksRouter = require('./routes/links');
var messageRouter = require('./routes/message');

var app = express();

// 配置 session 的中间件
// app.use(session({
//   secret: '#zyl1315mc#', // 服务器端生成 session 的签名
//   name: 'TokenKey', // 修改 session 对应的 cookie名称
//   resave: false, // 强制保存 session 即使它并没有变化
//   saveUninitialized: true, // 强制将未初始化的 session 存储
//   cookie: {
//     httpOnly: true,  // 客户端不能修改cookie
//     maxAge: 1000 * 60 * 60 * 24,
//     secure: false // true 表示只有 https 协议才能访问到 cookie
//   },
//   rolling: true, // 在每次请求时强行设置 cookie，这将重置 cookie 过期时间（默认：false）
//   // store: MongoStore.create({
//   //   mongoUrl: 'mongodb://localhost/sessionDB',
//   //   touchAfter: 24 * 3600 // 不管发出了多少请求 在 24小时内只更新一次 session 除非你改变了这个session
//   // })
// }))

// 数据库连接
require('./core/mongodb')

// require('./model/user')

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// var accessLog = fs.createWriteStream('../access.log', { flags: 'a' });
// var errorLog = fs.createWriteStream('../error.log', { flags: 'a' });

const NODE_ENV = process.env.NODE_ENV
// 使用日志、记录日志 -- dev 开发环境
// 详情可参考 https://github.com/expressjs/morgan
// 开发环境
var logDirectory = path.join(__dirname, 'logs')
// ensure log directory exists
fs.existsSync(logDirectory) || fs.mkdirSync(logDirectory)

// create a rotating write stream
var accessLogfile = FileStreamRotator.getStream({
  date_format: 'YYYY-MM-DD',
  filename: path.join(logDirectory, 'access-%DATE%.log'),
  frequency: 'daily',
  verbose: false
})

var errorLogfile = FileStreamRotator.getStream({
  date_format: 'YYYY-MM-DD',
  filename: path.join(logDirectory, 'error-%DATE%.log'),
  frequency: 'daily',
  verbose: false
})
// 对Date的扩展，将 Date 转化为指定格式的String
// 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符， 
// 年(y)可以用 1-4 个占位符，毫秒(S)只能用 1 个占位符(是 1-3 位的数字) 
// 例子： 
// (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423 
// (new Date()).Format("yyyy-M-d h:m:s.S")      ==> 2006-7-2 8:9:4.18 
Date.prototype.Format = function (fmt) { //author: meizz 
  var o = {
    "M+": this.getMonth() + 1, //月份 
    "d+": this.getDate(), //日 
    "h+": this.getHours(), //小时 
    "m+": this.getMinutes(), //分 
    "s+": this.getSeconds(), //秒 
    "q+": Math.floor((this.getMonth() + 3) / 3), //季度 
    "S": this.getMilliseconds() //毫秒 
  };
  if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
  for (var k in o)
    if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
  return fmt;
}


// 自定义token
logger.token('from', function (req, res) {
  return JSON.stringify(req.query) || '-';
});

logger.token('time', function (req, res) {
  return new Date().Format("yyyy-MM-dd hh:mm:ss");
});

logger.token('nextROw', function (req, res) {
  return "\r\n";
});

// 自定义format，其中包含自定义的token
logger.format('joke', '[joke] :time :remote-addr :remote-user :method :url :from :status :referrer :response-time ms :user-agent :nextROw');

//跳过不需要记录的请求
function skip (req) {
  return (req.url).indexOf('stylesheets') != -1
}
// 使用自定义的format
app.use(logger('joke'));
app.use(logger('joke', { skip: skip, stream: accessLogfile })); //打印到日志文件中  

app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use('/static', express.static(path.join(__dirname, 'static')));

app.use('/', indexRouter);
app.use('/users', usersRouter); // 用户路由
app.use('/roles', rolesRouter); // 角色路由
app.use('/menu', menusRouter); // 角色路由
app.use('/category', categoryRouter); // 文章分类路由
app.use('/tags', tagsRouter); // 文章分类路由
app.use('/article', articleRouter); // 文章分类路由
app.use('/links', linksRouter); // 友情链接路由
app.use('/message', messageRouter); // 留言板路由
// catch 404 and forward to error handler
app.use(function (req, res, next) {
  next(createError(404));
});

// error handler
app.use(function (err, req, res, next) {
  var now = new Date();
  var time = now.getFullYear() + '-' + now.getMonth() + '-' + now.getDate() + ' '
    + now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds();
  var meta = '[' + time + '] ' + req.method + ' ' + req.url + '\r\n';
  errorLogfile.write(meta + err.stack + '\r\n\r\n\r\n');
  next();
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;
